package com.csj.DesignPattern.proxy.jdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 获取代理对象工厂
public class ProxyFactory {

    // JDK动态代理的代理类，是属于目标类实现的接口的实现类，
    // 通俗说就是代理类和目标类需要实现同一个接口，而代理类也只能代理接口内的方法，无法代理目标类中的其他方法
    private TrainStation trainStation = new TrainStation();

    /*
        ClassLoader loader,类加载器 ，加载代理类
        Class<?>[] interfaces： 代理类实现的接口列表
        InvocationHandler h： 代理对象的调用处理程序
     */
    public SellTickets getProxyInstance() {
        SellTickets proxyInstance = (SellTickets) Proxy.newProxyInstance(
                trainStation.getClass().getClassLoader(),
                trainStation.getClass().getInterfaces(),
                new InvocationHandler() {
                    /*
                     * proxy：代理对象,即proxyInstance
                     * method：被代理对象要执行的方法，如 proxyPoint.sell(); 则method就是sell()方法
                     * args：代理对象要执行的方法参数，如 proxyPoint.sell(String name)方法，则args就是[name]
                     * return：被代理对象要执行的方法返回值，如 boolean isSuccess = proxyPoint.sell(name); 则return就是isSuccess
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 对代理类进行增强
                        System.out.println("代理点收取一些服务费用(JDK动态代理)");
                        // 返回值为被代理对象要执行的方法返回值
                        Object invoke = method.invoke(trainStation, args);
                        return invoke;
                    }
                }
        );
        return proxyInstance;
    }
}
/*
代理类实际长这样
public class $Proxy0 extends Proxy implements SellTickets {
    private static Method m0;
    public $Proxy0(InvocationHandler invocationHandler) {
        super(invocationHandler);
    }
    static {
        m0 = Class.forName("com.csj.proxy.staticProxy.SellTickets").getMethod("sell", new Class[0]);
    }
    public final void sell() {
        this.h.invoke(this, m0, null);
    }
}
这里的h和invocationHandler就是代理工厂中new的InvocationHandler()
        invoke就是匿名内部类中的invoke方法

 */
